%{
/*! @file Declarações de variáveis e funções utilizadas pelo analisador léxico
 *	Este arquivo é gerado automaticamente pelo Flex.
 */
#include <limits.h>
#include <stdio.h>
#include "hash.h"

FILE *file;
char err_path[NAME_MAX];

/*! @brief Controla a ação do analisador léxico
 * POLL_DIC quando está aguardando o caminho para o dicionário
 * POLL_TXT quando está aguardando o caminho para o arquivo texto
 * INSERT quando está lendo palavras do dicionário
 * SEARCH quando está lendo palavras do arquivo texto e buscando-as na tabela
 */
enum 
{
	POLL_DIC,
	POLL_TXT,
	INSERT,
	SEARCH
} scanner_action = POLL_DIC;

extern hash_t *table;
%}

%option yylineno
%option outfile="scanner.c"
%option header-file="scanner.h"

LETRA ([[:alpha:]]|[áéíóúàèìòùãẽĩõũâêîôûäëïöüñçÁÉÍÓÚÀÈÌÒÙÃẼĨÕŨÂÊÎÔÛÄËÏÖÜÑÇ])
PALAVRA {LETRA}+(-)?{LETRA}+
ARQUIVO {PALAVRA}[.]{PALAVRA}

%%

[sS]      {
	switch (scanner_action)
	{
		case POLL_DIC:
		case POLL_TXT:
			yyterminate();

		case INSERT: 
			hash_insert(table, yytext);
			break;

		case SEARCH:
			if (!hash_find(table, yytext))
				fprintf(stderr, "%s %d\n", yytext, yylineno);
			break;
	}
}

{ARQUIVO} {
	switch (scanner_action)
	{
		case POLL_DIC:
			file = fopen(yytext, "r");
			if (file)
			{
				yylineno = 0;
				yyin = file;
				scanner_action = INSERT;
			} else
			{
				printf("Erro ao abrir arquivo: %s\n", yytext);
				puts("Caminho para o arquivo dicionário ('s' para sair): ");
			}
			break;

		case POLL_TXT:
			file = fopen(yytext, "r");
			if (file)
			{
				yylineno = 0;
				yyin = file;
				scanner_action = SEARCH;
				strncpy(err_path, yytext, NAME_MAX);
				strncpy(strchr(err_path, '.') + 1, "err\0", 4);
				stderr = fopen(err_path, "w");
				if (stderr == NULL)
				{
					printf("Erro fatal: não consegui criar o arquivo de relatório %s\n Abortando!!!\n", err_path);
					exit(1);
				}
			} else
			{
				printf("Erro ao abrir arquivo: %s\n", yytext);
				puts("Caminho para o arquivo de texto ('s' para sair): ");
			}
			break;

		case INSERT: 
			printf("Erro no arquivo dicionário: palavra inválida: %s\n", yytext);
			break;

		case SEARCH:
			fprintf(stderr, "%s %d\n", yytext, yylineno);
			break;
	}
}

{PALAVRA} { 
	switch (scanner_action)
	{
		case POLL_DIC:
			printf("Nome de arquivo inválido: %s\n", yytext);
			puts("Caminho para o arquivo dicionário ('s' para sair): ");
			break;

		case POLL_TXT:
			printf("Nome de arquivo inválido: %s\n", yytext);
			puts("Caminho para o arquivo de texto ('s' para sair): ");
			break;

		case INSERT: 
			hash_insert(table, yytext);
			break;

		case SEARCH:
			if (! hash_find(table, yytext))
				fprintf(stderr, "%s %d\n", yytext, yylineno);
			break;
	}
}
\n
.

%%

/*! @brief controla a troca entre arquivos de entrada
 *	Regula a troca entre arquivos de entrada que são
 *	utilizados de maneira alternada pelo analisador para
 *	ler um nome de arquivo ou uma sequência de palavras
 *	do dicionário ou do arquivo texto. Esta função é
 *	utilizada internamente pelo analisador gerado pelo
 *  Flex.
 *
 *	@return 1 se a leitura acabou, 0 se um novo arquivo foi aberto para continuar a leitura.
 */
int yywrap() 
{
	switch (scanner_action)
	{
		case INSERT:
			puts("Caminho para o arquivo de texto ('s' para sair): ");
			scanner_action = POLL_TXT;
			yylineno = 0;
			yyin = stdin;
			return 0;

		case SEARCH:
			scanner_action = POLL_DIC;
			yylineno = 0;
			yyin = stdin;

			fclose(stderr);
			//hash_stats(table);
			hash_reset(table);
			puts("Caminho para o arquivo dicionário ('s' para sair): ");
			return 0;

		default:
			return 1;
	}
}
